home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * drag.c
- *
- * Text dragging routines. The code in this file implements the text
- * dragging features of this program. This is the single most important
- * file in the DragText program. The last function in this file,
- * DragText is called when a mouseDown is detected in the hilite region
- * of the current TextEdit field. To follow the text dragging code,
- * start with the DragText function.
- *
- *
- * Author: Rob Johnston
- * Date: Friday, September 10, 1993
- *
- * Copyright © 1992-93 Apple Computer, Inc.
- *
- */
-
- #include <QDOffscreen.h>
- #include <Folders.h>
- #include <Drag.h>
-
- #include "globals.h"
- #include "prototypes.h"
- #include "resources.h"
- #include "Offscreen.h"
-
-
- //
- // Can use custom drawing procedure.
- //
-
- // #define USE_CUSTOM_DRAWING
-
-
- static long caretTime;
- static short caretOffset, caretShow, lastOffset, insertPosition, canAcceptItems;
- static short cursorInContent;
-
-
- /*
- * The following #define statement provides access to TextEdit's caretTime.
- */
-
- #define gCaretTime ((short) *((long *) 0x02F4))
-
-
- /*
- * MyDrawingProc
- *
- * Simple drawing proc for dragging text. This drawing procedure is very similar to
- * the Drag Manager's built in drawing proc, except that it uses a solid black pattern
- * to draw the region instead of using the dithered gray pattern.
- */
-
- #ifdef USE_CUSTOM_DRAWING
-
- pascal OSErr MyDrawingProc(DragRegionMessage message,
- RgnHandle showRgn, Point showOrigin,
- RgnHandle hideRgn, Point hideOrigin,
- void *dragDrawingRefCon, DragReference theDragRef)
-
- { OSErr result = paramErr;
- RgnHandle tempRgn;
-
- switch(message) {
-
- case dragRegionBegin:
-
- //
- // No initialization necessary for our drawing proc. Make sure noErr
- // is returned, otherwise the Drag Manager will revert back to it's
- // built in drawing proc.
- //
-
- result = noErr;
- break;
-
- case dragRegionDraw:
-
- //
- // Find the difference between the region needed to be shown and the
- // region needed to be hidden. Inverting the difference removes the pixels
- // that must be hidden and shows the pixels that must be shown in one step.
- //
-
- XorRgn(showRgn, hideRgn, tempRgn = NewRgn());
- InvertRgn(tempRgn);
- DisposeRgn(tempRgn);
- result = noErr;
- break;
-
- case dragRegionHide:
-
- //
- // Simply hide the region given to us by inverting it.
- //
-
- InvertRgn(hideRgn);
- result = noErr;
- break;
- }
-
- return(result);
- }
-
- #endif USE_CUSTOM_DRAWING
-
-
- /*
- * Given a point in global coordinates, HitTest returns a pointer to a
- * document structure if the point is inside a document window on the screen.
- * If the point is not inside a document window, HitTest return NULL in
- * theDoc. If the point is in a doument window and also in the viewRect of
- * the document's TextEdit field, HitTest also returns the offset into
- * the text that corresponds to that point. If the point is not in the text,
- * HitTest returns -1.
- */
-
- short HitTest(Point theLoc, Document **theDoc)
-
- { WindowPtr theWindow;
- short offset;
-
- *theDoc = 0L;
- offset = -1;
-
- if (FindWindow(theLoc, &theWindow) == inContent) {
- if (*theDoc = IsDocumentWindow(theWindow)) {
-
- SetPort(theWindow);
- GlobalToLocal(&theLoc);
-
- if ((PtInRect(theLoc, &(**((**theDoc).theTE)).viewRect)) &&
- (PtInRect(theLoc, &(**((**theDoc).theTE)).destRect))) {
-
- offset = TEGetOffset(theLoc, (**theDoc).theTE);
-
- if ((TEIsFrontOfLine(offset, (**theDoc).theTE)) && (offset) &&
- ((*((**((**theDoc).theTE)).hText))[offset - 1] != 0x0D) &&
- (TEGetPoint(offset - 1, (**theDoc).theTE).h < theLoc.h)) {
- offset--;
- }
- }
- }
- }
-
- return(offset);
- }
-
-
- /*
- * DrawCaret draws a caret in a TextEdit field at the given offset. DrawCaret
- * expects the port to be set to the port that the TextEdit field is in.
- * DrawCaret inverts the image of the caret onto the screen.
- */
-
- short DrawCaret(short offset, TEHandle theTE)
-
- { Point theLoc;
- short theLine, lineHeight;
-
- /*
- * Get the coordinates and the line of the offset to draw the caret.
- */
-
- theLoc = TEGetPoint(offset, theTE);
- theLine = TEGetLine(offset, theTE);
-
- /*
- * For some reason, TextEdit dosen't return the proper coordinates
- * of the last offset in the field if the last character in the record
- * is a carriage return. TEGetPoint returns a point that is one line
- * higher than expected. The following code fixes this problem.
- */
-
- if ((offset == (**theTE).teLength) &&
- (*((**theTE).hText))[(**theTE).teLength - 1] == 0x0D) {
- theLoc.v += TEGetHeight(theLine, theLine, theTE);
- }
-
- /*
- * Always invert the caret when drawing.
- */
-
- PenMode(patXor);
-
- /*
- * Get the height of the line that the offset points to.
- */
-
- lineHeight = TEGetHeight(theLine, theLine, theTE);
-
- /*
- * Draw the appropriate caret image.
- */
-
- MoveTo(theLoc.h - 1, theLoc.v - 1);
- Line(0, 1 - lineHeight);
-
- PenNormal();
- }
-
-
- char GetCharAtOffset(short offset, TEHandle theTE)
-
- {
- if (offset < 0)
- return(0x0D);
-
- return(((char *) *((**theTE).hText))[offset]);
- }
-
-
- Boolean WhiteSpace(char theChar)
-
- {
- return((theChar == ' ') || (theChar == 0x0D));
- }
-
-
- Boolean WhiteSpaceAtOffset(short offset, TEHandle theTE)
-
- { char theChar;
-
- if ((offset < 0) || (offset > (**theTE).teLength - 1))
- return(true);
-
- theChar = ((char *) *((**theTE).hText))[offset];
- return((theChar == ' ') || (theChar == 0x0D));
- }
-
-
- void InsertTextAtOffset(short offset, char *theBuf, long size, StScrpHandle theStyl, TEHandle theTE)
-
- {
- if (size == 0)
- return;
-
- //
- // If inserting at the end of a word and the selection does not begin with
- // a space, insert a space before the insertion.
- //
-
- if (!WhiteSpaceAtOffset(offset - 1, theTE) &&
- WhiteSpaceAtOffset(offset, theTE) &&
- !WhiteSpace(theBuf[0])) {
-
- TESetSelect(offset, offset, theTE);
- TEKey(' ', theTE);
- offset++;
- }
-
- //
- // If inserting at the beginning of a word and the selection does not end
- // with a space, insert a space after the insertion.
- //
-
- if ( WhiteSpaceAtOffset(offset - 1, theTE) &&
- !WhiteSpaceAtOffset(offset, theTE) &&
- !WhiteSpace(theBuf[size - 1])) {
-
- TESetSelect(offset, offset, theTE);
- TEKey(' ', theTE);
- }
-
- TESetSelect(offset, offset, theTE);
- TEStylInsert(theBuf, size, theStyl, theTE);
- TESetSelect(offset, offset + size, theTE);
- }
-
-
- short GetSelectionSize(Document *theDocument)
-
- {
- return((**(theDocument->theTE)).selEnd - (**(theDocument->theTE)).selStart);
- }
-
-
- Ptr GetSelectedTextPtr(Document *theDocument)
-
- {
- return((*(**(theDocument->theTE)).hText) + (**(theDocument->theTE)).selStart);
- }
-
-
- /*
- * MySendDataProc
- *
- * Will provide 'styl' data for the drag when requested.
- */
-
- pascal OSErr MySendDataProc(FlavorType theType, void *refCon,
- ItemReference theItem, DragReference theDrag)
-
- { Document *theDocument = (Document *) refCon;
- StScrpHandle theStyl;
-
- if (theType == 'styl') {
-
- theStyl = GetStylScrap(theDocument->theTE);
-
- //
- // Call SetDragItemFlavorData to provide the requested data.
- //
-
- HLock((Handle) theStyl);
- SetDragItemFlavorData(theDrag, theItem, 'styl', (Ptr) *theStyl,
- GetHandleSize((Handle) theStyl), 0L);
- HUnlock((Handle) theStyl);
- DisposeHandle((Handle) theStyl);
-
- } else {
-
- return(badDragFlavorErr);
-
- }
-
- return(noErr);
- }
-
-
- /*
- * MyReceiveDropHandler
- *
- * Called by the Drag Manager when a drop occurs over one of the DragText document windows.
- */
-
- pascal OSErr MyReceiveDropHandler(WindowPtr theWindow, unsigned long handlerRefCon,
- DragReference theDrag)
-
- { OSErr result;
- TEHandle tempTE;
- Rect theRect, srcRect;
- unsigned short items, index;
- ItemReference theItem;
- DragAttributes attributes;
- Ptr textData;
- StScrpHandle stylHandle;
- Size textSize, stylSize;
- short offset, selStart, selEnd, mouseDownModifiers, mouseUpModifiers, moveText;
- Document *theDocument = (Document *) handlerRefCon;
- WindowOffscreen *theOffscreen;
- Point thePoint;
-
- if ((!canAcceptItems) || (insertPosition == -1))
- return(dragNotAcceptedErr);
-
- SetPort(theWindow);
-
- GetDragAttributes(theDrag, &attributes);
- GetDragModifiers(theDrag, 0L, &mouseDownModifiers, &mouseUpModifiers);
-
- moveText = (attributes & dragInsideSenderWindow) &&
- (!((mouseDownModifiers & optionKey) | (mouseUpModifiers & optionKey)));
-
- //
- // Loop through all of the drag items contained in this drag and collect the text
- // into the tempTE record.
- //
-
- SetRect(&theRect, 0, 0, 0, 0);
- tempTE = TEStylNew(&theRect, &theRect);
-
- CountDragItems(theDrag, &items);
-
- for (index = 1; index <= items; index++) {
-
- //
- // Get the item's reference number, so we can refer to it.
- //
-
- GetDragItemReferenceNumber(theDrag, index, &theItem);
-
- //
- // Try to get the flags for a 'TEXT' flavor. If this returns noErr,
- // then we know that a 'TEXT' flavor exists in the item.
- //
-
- result = GetFlavorDataSize(theDrag, theItem, 'TEXT', &textSize);
-
- if (result == noErr) {
-
- textData = NewPtr(textSize);
- if (textData == 0L) {
- TEDispose(tempTE);
- return(memFullErr);
- }
-
- GetFlavorData(theDrag, theItem, 'TEXT', textData, &textSize, 0L);
-
- //
- // Check for optional styl data for the TEXT.
- //
-
- stylHandle = 0L;
- result = GetFlavorDataSize(theDrag, theItem, 'styl', &stylSize);
- if (result == noErr) {
-
- stylHandle = (StScrpHandle) NewHandle(stylSize);
- if (stylHandle == 0L) {
- TEDispose(tempTE);
- DisposePtr(textData);
- return(memFullErr);
- }
-
- HLock((Handle) stylHandle);
- GetFlavorData(theDrag, theItem, 'styl', *stylHandle, &stylSize, 0L);
- HUnlock((Handle) stylHandle);
-
- }
-
- //
- // Insert this drag item's text into the tempTE.
- //
-
- TESetSelect(32767, 32767, tempTE);
- TEStylInsert(textData, textSize, stylHandle, tempTE);
-
- DisposePtr(textData);
- if (stylHandle)
- DisposeHandle((Handle) stylHandle);
- }
- }
-
- //
- // Pull the TEXT and styl data out of the tempTE handle.
- //
-
- textData = NewPtr(textSize = (**tempTE).teLength);
- if (textData == 0L) {
- TEDispose(tempTE);
- return(memFullErr);
- }
- BlockMove(*(**tempTE).hText, textData, textSize);
-
- TESetSelect(0, 32767, tempTE);
- stylHandle = GetStylScrap(tempTE);
-
- TEDispose(tempTE);
-
- //
- // If we actually received text, insert it into the destination.
- //
-
- if (textSize != 0) {
-
- //
- // If the caret or highlighting is on the screen, remove it/them.
- //
-
- offset = caretOffset;
-
- if (caretOffset != -1) {
- DrawCaret(caretOffset, theDocument->theTE);
- caretOffset = -1;
- }
-
- if (attributes & dragHasLeftSenderWindow) {
- HideDragHilite(theDrag);
- }
-
- //
- // If the drag occurred completely within the same window and the window is not
- // frontmost, bring the window forward and update its contents before completing
- // the drag.
- //
-
- if ((attributes & dragInsideSenderWindow) && (theDocument->theWindow != FrontWindow())) {
- SelectWindow(theDocument->theWindow);
- UpdateWindow(theDocument);
- TEActivate(theDocument->theTE);
- }
-
- //
- // Draw everything into offscreen pixmap.
- //
-
- if (theOffscreen = DrawOffscreen(theDocument->theWindow)) {
- (**(theDocument->theTE)).inPort = (GrafPtr) theOffscreen->offscreenWorld;
- }
-
- //
- // If the window is not active, must activate TE before inserting
- // text or the background hilite will not update correctly.
- //
-
- if (!((WindowPeek) theDocument->theWindow)->hilited) {
- TEActivate(theDocument->theTE);
- }
-
- //
- // If this window is also the sender, delete source selection if no
- // option key.
- //
-
- if (moveText) {
- selStart = (**(theDocument->theTE)).selStart;
- selEnd = (**(theDocument->theTE)).selEnd;
- if ( WhiteSpaceAtOffset(selStart - 1, theDocument->theTE) &&
- !WhiteSpaceAtOffset(selStart, theDocument->theTE) &&
- !WhiteSpaceAtOffset(selEnd - 1, theDocument->theTE) &&
- WhiteSpaceAtOffset(selEnd, theDocument->theTE)) {
-
- if (GetCharAtOffset(selEnd, theDocument->theTE) == ' ')
- (**(theDocument->theTE)).selEnd++;
- }
- if (insertPosition > selStart) {
- insertPosition -= ((**(theDocument->theTE)).selEnd -
- (**(theDocument->theTE)).selStart);
- }
- srcRect = (**theDocument->hiliteRgn).rgnBBox;
- TEDelete(theDocument->theTE);
- }
-
- InsertTextAtOffset(insertPosition, textData, textSize, stylHandle, theDocument->theTE);
-
- TEGetHiliteRgn(theDocument->hiliteRgn, theDocument->theTE);
-
- //
- // If the text is moving (not copying) within the same window, provide a ZoomRects
- // from the source to the destination before revealing the reflowed text.
- //
-
- if (moveText) {
- theRect = (**theDocument->hiliteRgn).rgnBBox;
- thePoint.h = thePoint.v = 0;
- SetPort(theWindow);
- LocalToGlobal(&thePoint);
- OffsetRect(&srcRect, thePoint.h, thePoint.v);
- OffsetRect(&theRect, thePoint.h, thePoint.v);
- ZoomRects(&srcRect, &theRect, 12, zoomDecelerate);
- }
-
- theDocument->dirty = true;
- }
-
- DisposePtr(textData);
-
- if (stylHandle)
- DisposeHandle((Handle) stylHandle);
-
- //
- // Undo the TEActivate, if needed.
- //
-
- if (!((WindowPeek) theDocument->theWindow)->hilited) {
- TEDeactivate(theDocument->theTE);
- }
-
- //
- // Show the offscreen bitmap.
- //
-
- DrawOnscreen(theOffscreen);
- (**(theDocument->theTE)).inPort = theDocument->theWindow;
-
- return(noErr);
- }
-
-
- /*
- * MyTrackingHandler
- *
- * This is the drag tracking handler for windows in the DragText application.
- */
-
- pascal OSErr MyTrackingHandler(short message, WindowPtr theWindow,
- void *handlerRefCon, DragReference theDrag)
-
- { short result, offset;
- long theTime = TickCount();
- unsigned short count, index;
- unsigned long flavorFlags, attributes;
- ItemReference theItem;
- RgnHandle theRgn;
- Document *theDocument = (Document *) handlerRefCon;
- Document *hitDoc;
- Point theMouse, localMouse;
-
- if ((message != dragTrackingEnterHandler) && (!canAcceptItems))
- return(noErr);
-
- GetDragAttributes(theDrag, &attributes);
-
- switch (message) {
-
- case dragTrackingEnterHandler:
-
- //
- // We get called with this message the first time that a drag enters ANY
- // window in our application. Check to see if all of the drag items contain
- // TEXT. We only accept a drag if all of the items in the drag can be accepted.
- //
-
- canAcceptItems = true;
-
- CountDragItems(theDrag, &count);
-
- for (index = 1; index <= count; index++) {
- GetDragItemReferenceNumber(theDrag, index, &theItem);
-
- result = GetFlavorFlags(theDrag, theItem, 'TEXT', &flavorFlags);
-
- if (result != noErr) {
- canAcceptItems = false;
- break;
- }
- }
-
- break;
-
- case dragTrackingEnterWindow:
-
- //
- // We receive an EnterWindow message each time a drag enters one of our
- // application's windows. We initialize our global variables for tracking
- // the drag through the window.
- //
-
- caretTime = theTime;
- caretOffset = lastOffset = -1;
- caretShow = true;
-
- cursorInContent = false;
-
- break;
-
- case dragTrackingInWindow:
-
- //
- // We receive InWindow messages as long as the mouse is in one of our windows
- // during a drag. We draw the window highlighting and blink the insertion caret
- // when we get these messages.
- //
-
- GetDragMouse(theDrag, &theMouse, 0L);
- localMouse = theMouse;
- GlobalToLocal(&localMouse);
-
- //
- // Show or hide the window highlighting when the mouse enters or leaves the
- // TextEdit field in our window (we don't want to show the highlighting when
- // the mouse is over the window title bar or over the scroll bars).
- //
-
- if (attributes & dragHasLeftSenderWindow) {
- if (PtInRect(localMouse, &(**(theDocument->theTE)).viewRect)) {
-
- if (!cursorInContent) {
- RectRgn(theRgn = NewRgn(), &(**(theDocument->theTE)).viewRect);
- ShowDragHilite(theDrag, theRgn, true);
- DisposeRgn(theRgn);
- }
- cursorInContent = true;
-
- } else {
-
- if (cursorInContent) {
- HideDragHilite(theDrag);
- }
- cursorInContent = false;
-
- }
- }
-
- offset = HitTest(theMouse, &hitDoc);
-
- //
- // If this application is the sender, do not allow tracking through
- // the selection in the window that sourced the drag.
- //
-
- if (attributes & dragInsideSenderWindow) {
- if ((offset >= (**(theDocument->theTE)).selStart) &&
- (offset <= (**(theDocument->theTE)).selEnd)) {
- offset = -1;
- }
- }
-
- if (hitDoc == theDocument) {
-
- insertPosition = offset;
-
- //
- // Reset flashing counter if the offset has moved. This makes the
- // caret blink only after the caret has stopped moving long enough.
- //
-
- if (offset != lastOffset) {
- caretTime = theTime;
- caretShow = true;
- }
- lastOffset = offset;
-
- //
- // Flash caret.
- //
-
- if (theTime - caretTime > gCaretTime) {
- caretShow = !caretShow;
- caretTime = theTime;
- }
- if (! caretShow) {
- offset = -1;
- }
-
- //
- // If caret offset has changed, move caret on screen.
- //
-
- if (offset != caretOffset) {
- if (caretOffset != -1) {
- DrawCaret(caretOffset, theDocument->theTE);
- }
- if (offset != -1) {
- DrawCaret(offset, theDocument->theTE);
- }
- }
-
- caretOffset = offset;
-
- } else {
-
- lastOffset = offset;
- insertPosition = -1;
-
- }
-
- break;
-
- case dragTrackingLeaveWindow:
-
- //
- // If the caret is on the screen, remove it.
- //
-
- if (caretOffset != -1) {
- DrawCaret(caretOffset, theDocument->theTE);
- caretOffset = -1;
- }
-
- //
- // Remove window highlighting, if showing.
- //
-
- if ((cursorInContent) && (attributes & dragHasLeftSenderWindow))
- HideDragHilite(theDrag);
-
- break;
-
- case dragTrackingLeaveHandler:
- break;
-
- }
-
- return(noErr);
- }
-
-
- /*
- * DropLocationIsFinderTrash
- *
- * Returns true if the given dropLocation AEDesc is a descriptor of the Finder's Trash.
- */
-
- Boolean DropLocationIsFinderTrash(AEDesc *dropLocation)
-
- { OSErr result;
- AEDesc dropSpec;
- FSSpec *theSpec;
- CInfoPBRec thePB;
- short trashVRefNum;
- long trashDirID;
-
- //
- // Coerce the dropLocation descriptor to an FSSpec. If there's no dropLocation or
- // it can't be coerced into an FSSpec, then it couldn't have been the Trash.
- //
-
- if ((dropLocation->descriptorType != typeNull) &&
- (AECoerceDesc(dropLocation, typeFSS, &dropSpec) == noErr)) {
-
- HLock(dropSpec.dataHandle);
- theSpec = (FSSpec *) *dropSpec.dataHandle;
-
- //
- // Get the directory ID of the given dropLocation object.
- //
-
- thePB.dirInfo.ioCompletion = 0L;
- thePB.dirInfo.ioNamePtr = (StringPtr) &theSpec->name;
- thePB.dirInfo.ioVRefNum = theSpec->vRefNum;
- thePB.dirInfo.ioFDirIndex = 0;
- thePB.dirInfo.ioDrDirID = theSpec->parID;
-
- result = PBGetCatInfo(&thePB, false);
-
- HUnlock(dropSpec.dataHandle);
- AEDisposeDesc(&dropSpec);
-
- if (result != noErr)
- return(false);
-
- //
- // If the result is not a directory, it must not be the Trash.
- //
-
- if (!(thePB.dirInfo.ioFlAttrib & (1 << 4)))
- return(false);
-
- //
- // Get information about the Trash folder.
- //
-
- FindFolder(theSpec->vRefNum, kTrashFolderType, kCreateFolder, &trashVRefNum, &trashDirID);
-
- //
- // If the directory ID of the dropLocation object is the same as the directory ID
- // returned by FindFolder, then the drop must have occurred into the Trash.
- //
-
- if (thePB.dirInfo.ioDrDirID == trashDirID)
- return(true);
- }
-
- return(false);
- }
-
-
- /*
- * DragText
- *
- * Drag the selected text in the given document.
- */
-
- short DragText(Document *theDocument, EventRecord *theEvent, RgnHandle hiliteRgn)
-
- { short result;
- RgnHandle dragRegion, tempRgn;
- Point theLoc;
- DragReference theDrag;
- StScrpHandle theStyl;
- AEDesc dropLocation;
- DragAttributes attributes;
- short mouseDownModifiers, mouseUpModifiers, copyText;
-
- //
- // Copy the hilite region into dragRegion and offset it into global coordinates.
- //
-
- CopyRgn(hiliteRgn, dragRegion = NewRgn());
- SetPt(&theLoc, 0, 0);
- LocalToGlobal(&theLoc);
- OffsetRgn(dragRegion, theLoc.h, theLoc.v);
-
- //
- // Wait for the mouse to move to the mouse button to be released. If the mouse button was
- // released before the mouse moves, return false. Returing false from DragText means that
- // a drag operation did not occur.
- //
-
- if (! WaitMouseMoved(theEvent->where)) {
- return(false);
- }
-
- NewDrag(&theDrag);
-
- //
- // For purposes of demonstration, we insert the 'TEXT' data and promise 'styl'
- // data. If a receiver requests 'TEXT', the Drag Manager will give them the text
- // without needing us to intervene. If a receiver requests 'styl', the Drag Manager
- // will call our MySendDataProc to provide the data at drop time. The MySendDataProc
- // is specified by calling SetDragSendProc.
- //
-
- AddDragItemFlavor(theDrag, 1, 'TEXT', GetSelectedTextPtr(theDocument),
- GetSelectionSize(theDocument), 0);
-
- theStyl = GetStylScrap(theDocument->theTE);
- HLock((Handle) theStyl);
- AddDragItemFlavor(theDrag, 1, 'styl', (Ptr) *theStyl, GetHandleSize((Handle) theStyl), 0);
- HUnlock((Handle) theStyl);
- DisposeHandle((Handle) theStyl);
-
- SetDragSendProc(theDrag, MySendDataProc, (void *) theDocument);
-
- //
- // Set the item's bounding rectangle in global coordinates.
- //
-
- SetDragItemBounds(theDrag, 1, &(**dragRegion).rgnBBox);
-
- //
- // Prepare the drag region.
- //
-
- tempRgn = NewRgn();
- CopyRgn(dragRegion, tempRgn);
- InsetRgn(tempRgn, 1, 1);
- DiffRgn(dragRegion, tempRgn, dragRegion);
- DisposeRgn(tempRgn);
-
- #ifdef USE_CUSTOM_DRAWING
-
- SetDragDrawingProc(theDrag, MyDrawingProc, 0L);
-
- #endif
-
- //
- // Drag the text. TrackDrag will return userCanceledErr if the drop zoomed-back
- // for any reason.
- //
-
- result = TrackDrag(theDrag, theEvent, dragRegion);
-
- if (result != noErr && result != userCanceledErr) {
- return(true);
- }
-
- //
- // Check to see if the drop occurred in the Finder's Trash. If the drop occurred
- // in the Finder's Trash and a copy operation wasn't specified, delete the
- // source selection. Note that we can continute to get the attributes, drop location
- // modifiers, etc. of the drag until we dispose of it using DisposeDrag.
- //
-
- GetDragAttributes(theDrag, &attributes);
- if (!(attributes & dragInsideSenderApplication)) {
-
- GetDropLocation(theDrag, &dropLocation);
-
- GetDragModifiers(theDrag, 0L, &mouseDownModifiers, &mouseUpModifiers);
- copyText = (mouseDownModifiers | mouseUpModifiers) & optionKey;
-
- if ((!copyText) && (DropLocationIsFinderTrash(&dropLocation))) {
- TEDelete(theDocument->theTE);
- theDocument->dirty = true;
- }
-
- AEDisposeDesc(&dropLocation);
- }
-
- //
- // Dispose of the drag.
- //
-
- DisposeDrag(theDrag);
-
- DisposeRgn(dragRegion);
-
- return(true);
- }
-
-
-
-
-